package model

import (
	"fmt"
	"log"
	"youdu/config"
	"youdu/driver/dm"
	versionControlMigration "youdu/migrator/jielong"
	initMigration "youdu/migrator/jielong/v0"

	// modelJielong "youdu/model/jielong"

	"github.com/go-gormigrate/gormigrate/v2"
	"gorm.io/gorm"
)

var Db *gorm.DB

func InitDB() error {
	db, err := connect()
	if err != nil {
		return err
	}
	if err = initMigrate(db); err != nil {
		return err
	}
	if err = upgradeLatestMigrate(db); err != nil {
		return err
	}
	// 成功返回
	Db = db
	return nil
}

func connect() (*gorm.DB, error) {
	// 使用配置文件值
	host := config.Inst.Database.Host
	port := config.Inst.Database.Port
	user := config.Inst.Database.User
	pass := config.Inst.Database.Password
	name := config.Inst.Database.DbName
	dsn := "dm://" + user + ":" + pass + "@" + host + ":" + port + "/?autoCommit=true"
	// 连接到达梦数据库（使用 SYSDBA 用户并连接到默认数据库）
	db, err := gorm.Open(dm.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatalf("failed to connect to database: %v", err)
		return nil, err
	}
	// 创建新的数据库
	db.Exec(fmt.Sprintf("CREATE SCHEMA \"%s\"  AUTHORIZATION SYSDBA", name))
	// 连接到达梦数据库（使用 SYSDBA 用户并连接到新的数据库）
	dsn2 := dsn + "&schema=" + name
	// dsn = "dm://SYSDBA:SYSDBA001@172.22.0.82:5236/?schema=Youdu_Jielong_Demo&autoCommit=true"
	db, err = gorm.Open(dm.Open(dsn2), &gorm.Config{})
	if err != nil {
		log.Fatalf("failed to connect to database: %v", err)
		return nil, err
	}
	log.Printf("Current Database: %s", db.Migrator().CurrentDatabase())
	// 成功返回
	return db, nil
}

var migrationOptions = gormigrate.Options{
	// UseTransaction:            true, // 使用 PostgreSQL 事务机制。
	// ValidateUnknownMigrations: true,  // 使用非法 migrations 记录校验。
}

func initMigrate(db *gorm.DB) error {
	m := gormigrate.New(db, &migrationOptions, []*gormigrate.Migration{})

	m.InitSchema(func(tx *gorm.DB) error {
		err := tx.AutoMigrate(initMigration.ModelSchemaList...)
		if err != nil {
			return err
		}
		return nil
	})

	if err := m.Migrate(); err != nil {
		log.Fatalf("Could not migrate init: %v", err)
		// m.RollbackLast()
		return err
	}
	log.Printf("Init Migration successfully")
	return nil
}

func upgradeLatestMigrate(db *gorm.DB) error {
	if len(versionControlMigration.ModelSchemaList) == 0 {
		log.Printf("No need to migrate upgrade")
		return nil
	}
	m := gormigrate.New(db, &migrationOptions, versionControlMigration.ModelSchemaList)

	if err := m.Migrate(); err != nil {
		log.Fatalf("Could not migrate upgrade: %v", err)
		// m.RollbackLast()
		return err
	}
	log.Printf("Upgrade Latest Migration successfully")
	return nil
}
